디자인 설계는 왜 필요할까?

위의 화면 디자인을 개발한다고 가정을 해보자. 여기서 다음과 같은 조건이 붙는다.
- 해당 디자인은 공지사항 페이지뿐만 아니라 QnA , 채용게시판등등 여러페이지에서 재사용 된다.
- 모든 페이지에서 디자인이 상이할 수 있지만, 레이아웃의 큰 틀은 변하지 않는다.
- 기능은 다음과같이 리스트가 보여지며, 리스트에 관련된 필터기능과 검색기능이 있어야한다.
- 페이지네이션이 필요하며, 리스트가 없을때의 화면도 고려한다.
우리는 여기서, 제일 중요한 단어를 발견해야한다. 공지사항 뿐만 아니라, 다른 페이지에서도 이와같은 레이아웃으로 재사용 한다는 점이다.
만약 디자인 설계를 하지않고 개발한다면?
디자인 설계가 필요한 이유를 찾는다면 하지않았을 때의 단점을 찾는 것이 제일 빠를 수 있다. 만약 위의 내용을 디자인 패턴없이 각자 개발한다고 가정해보자. 한 사람이 아니라 여러사람이 개발할 것이고, 페이지마다 담당자가 생길 것이다. 우리는 곧 서로가 같은 레이아웃을 각자 다른 방법으로 개발하는 모습을 발견하게 될 것이며, 이는 비효율적이라 생각할 것이다. 위의 레이아웃에서 변한게 있는가? 어떤 사람은 flex 스타일로, 어떤 사람은 grid스타일로 구성할 것이며, 기능 또한 같은 기능이지만 서로다른 로직으로 개발할 것이다.
유지보수는 또 어떠한가?
SI특성상 구축한 이 후, 고객에게 운영을 넘겨주어야 한다. 단순히 구축에서는 개발만 하면 큰 상관이 없을 수 있지만, 일반적으로 운영은 구축보다 더 적은 인원으로 이루어진다. 한 두명이 여러페이지를 관리해야하는 상황이 발생한다. 하지만 패턴없이 페이지마다 각자만의 코드패턴을 파악해야한다. 같은 비즈니스 로직인데도 말이다. 이는 유지보수 측면에서도 절대 좋지않을 것이다.
디자인 설계의 장점
내가 생각하는 디자인 설계의 장점은 다음과 같다.
- 공동 개발을 위한 컨벤션을 제공함으로서 코드의 충돌이나 오류를 피하고, 전체 프로세스를 최적화하기 위한 가이드제공
- 재사용이 가능한 구성요소를 제공하고, 이로써 시간절약과 업무 효율을 증가시킵니다. 새로운 페이지를 마주할 때마다 처음부터 주기를 다시 개발할 필요가 없어집니다.
- 체계적인 방법을 제공함으로서, 규모가 있는 프로젝트를 개발할 경우, 페이지마다 일관된 패턴으로 구성함으로서 유지관리가 쉬워집니다.
- 수정해야하는 부분이 있으면 여러곳이 아닌 한 곳만 바라볼 수 있어 확장성에 유리합니다.
이번 프로젝트에서 제일 큰 장점으로 다가왔던 것은 위의 장점중에서 시간절약과 업무효율의 증가라고 생각한다. 프로젝트 기간이 실제 프론트 업무만 봤을때 2달정도 밖에 없었다. 그마저도 나머지 한달은 api가 개발되기전 mock data로 UI를 개발해야하는 기간이라 실질적인 api바인딩 기간은 한달정도였다. 하지만 디자인패턴으로 우리는 페이지를 효율적으로 개발하여 일정에 무리없이 맞출 수 있었다.
디자인패턴 어떤 걸 적용해볼까?
장점은 충분히 알겠다! 이제 어떤 디자인 패턴을 적용해볼까 고민해보자. 리액트 패턴 - 공식문서](https://www.patterns.dev/react/hoc-pattern)를 참고해보면 다양한 디자인 패턴이 설명되어있다. 내가 추구하는 디자인 패턴은 유연성이다. 화면마다 기획마다 페이지의 패턴은 다른데, 디자인 패턴만 일정하다면 과연 높은 효율을 가질 수 있을까? 생각했다. 해당 페이지에 가장 잘맞는 디자인 패턴을 상황에따라 적용해야한다고 생각한다. 무조건 HOC패턴만 고집하고, Compound패턴만 고집하는 것은 지양하고자 했다. 위의 사진에서 내가 제일 효율적이라고 생각한 패턴은 아토믹 디자인 패턴과 Hooks 패턴이다.
Atomic Pattern
아토믹 디자인패턴은 간단히 정리하자면, 가장 작은 단위(atom)부터 시작해서 분자(molecules), 유기체(organism)로 점점 확장하며 최종적으로 조립하여 한 페이지를 구성하는 패턴입니다. 이렇게하면 UI의 재사용을 극대화 할 수있습니다. 하지만 이 디자인패턴을 고려할 때 제일 주의해야하는 점은 너무 세분화하거나 재사용성의 목적만을 생각하여 깊은 deps의 패턴을 구성하는 것을 조심해야한다. 오히려 너무 깊은 deps는 개발자에게 필요없는 피로도를 줄 뿐이다. 이부분은 추후 설명하면서 좀 더 자세하게 다루겠다.

아토믹으로 디자인 했을 때, 구성한 요소는 다음과 같습니다.
- green : atom
- Red / grey / purple : Molecules
- black : organism
- template : 전체구성요소의 합
해당 페이지에서 직접 global style형식으로 스타일을 적용하여 컴포넌트를 너무 세분화하지않도록 방지하였다. 페이지마다 디테일한 스타일 요소가 다르기때문에, 이를 직접 페이지마다 커스텀하기 쉽도록 구성하기 위함이었다.

Atom
먼저 아톰인 초록색부터 살펴보면, 박스형태인 가장 작은 단위로 구성되어있습니다.
export const FilterItem = ({ children, label, ...others }: FilterItemProps) => {
const { textcolor, required} = others
return (
<div className="item">
<InputGroup align="inline">
<InputLabel labelText={label} textcolor={textcolor} required={required} />
{children}
</InputGroup>
</div>
)
}
export default FilterItem해당컴포넌트는 FilterItem으로 지정하였습니다. 필터의 필요한 아이템이라는 의미이고, 아이템이라는 것은 리스트를 구성하는 작은단위이므로 아톰에 어울린다고 생각하였습니다. 위의 소스를 보시면, 기능적인 부분은 일절 관여하지 않고, 오직 UI만 담당하고 있는 것을 볼 수 있습니다. 그리고 props도 꼭 필요한 부분만 받고 있으며 나머진 칠드론으로 구성하도록 하였습니다. UI만 담당함으로서, 기능적인 측면을 배제하고 UI 스타일에만 집중할 수 있습니다.
<FilterItem label="Period">
<DateRangePicker/>
</FilterItem>
<FilterItem label="Type">
<SelectMui/>
</FilterItem>이렇게, FilterItem안에 알맞는 컴포넌트를 구성함으로서 페이지마다 개발자가 쉽게 커스텀하기 편하도록 구성하였습니다. 필터아이템은 공통적으로 사용되는 마진과 패딩요소, 그리고 필터에 필요한 라벨만 받습니다.
molecules
<div className="align">
<div className="lft gap_10">
<FilterItem label="Period">
<DateRangePicker/>
</FilterItem>
<FilterItem label="Type">
<SelectMui/>
</FilterItem>
<FilterItem label="Keyword">
<div className="grid6">
<SearchIcoInput>
<SelectMui/>
</SearchIcoInput>
</div>
</FilterItem>
<ButtonMui/>
</div>
</div>위에서 말했던 것처럼, 모큘러스에 컴포넌트를 제공하지않고 스타일로 적용하여 구성하였다. 페이지마다 디테일한 구성요소가 다르기 때문이다. 위의 화면에서는 날짜 인풋창과 카테고리 셀렉트박스, 검색창 모두 왼쪽으로 제공되어진다. 하지만 다른페이지에서는 날짜 인풋창과 카테고리가 왼쪽이고, 검색창이 오른쪽으로 배치되는 경우도 있다. 이럴경우에는 className을 rgt로 넣어만 주면 쉽게 UI를 배치할 수 있지만, 이부분을 컴포넌트로 제공한다면 left / right를 분기처리하여 chlidren으로 받게된다. 이를 global scss로 적용하는게 훨씬 간단하다. 이렇게 align을 맞춰줍니다.
organism
<ContentBox>
<div className="align">
<div className="lft gap_10">
<FilterItem label="Period">
<DateRangePicker/>
</FilterItem>
<FilterItem label="Type">
<SelectMui/>
</FilterItem>
<FilterItem label="Keyword">
<div className="grid6">
<SearchIcoInput>
<SelectMui/>
</SearchIcoInput>
</div>
</FilterItem>
<ButtonMui/>
</div>
</div>
{!isParamsLoading && <NoticeTable />}
</ContentBox>ContentBox 컴포넌트로 organism을 형성합니다. 이부분이 바로 black영역이다. 테이블영역과 필터부분이 합쳐져서 실제 페이지의 인터페이스가 어떻게 구성되는지 알 수있게되는 단계이다. ContentBox컴포넌트도 필터아이템과 동일하게 UI만 관리할 수 있도록하였다. 이제 다른 페이지에서도 이런 형식으로 일관된 코드를 구성할 수 있게되었으며, 개발속도가 엄청 증가하게 될 것이다.